// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: tianqiang

#pragma once

#include <memory>

#include <grpcpp/grpcpp.h>

#include "coin2/exchange/base/api_base/grpc/grpc_context.h"

namespace coin2::exchange::base::order {
struct OrderExecution;
struct LiquiditySpec;
}  // namespace coin2::exchange::base::order

namespace coin2::exchange::base::api_base::grpc {

class GrpcTradeClient {
 public:
  using Callback = std::function<void(std::shared_ptr<GrpcContext>)>;
  using OrderExecution = coin2::exchange::base::order::OrderExecution;
  using LiquiditySpec = coin2::exchange::base::order::LiquiditySpec;

  GrpcTradeClient() = default;
  virtual ~GrpcTradeClient() = default;

  GrpcTradeClient(const GrpcTradeClient&) = delete;
  GrpcTradeClient& operator=(const GrpcTradeClient&) = delete;

  void SetCallback(Callback callback) { callback_ = callback; }

  void OnResponse(std::shared_ptr<GrpcContext> grpc_context, ::grpc::Status s) {
    grpc_context->status = s;

    callback_(grpc_context);
  }

  virtual void PlaceOrder(const OrderExecution&) = 0;
  virtual void CancelOrder(const OrderExecution&) = 0;
  virtual void SubmitLiquidity(const LiquiditySpec&) {
    CHECK(false) << "SubmitLiquidity is not implemented";
    return;
  }

 private:
  Callback callback_;
};

}  // namespace coin2::exchange::base::api_base::grpc
